// // 初始化参数 默认值是undefined
// function test(a = undefined, b){ 
//   console.log(a);
//   console.log(b);
// }
// // 实参或者形参中有一个undefined时，用默认值
// test(1 ,2)

// 添加默认参数
// function test(a, b){
//   var a = arguments[0] || 1;
//   var b = arguments[1] || 2;

//   console.log(a + b);
// }

// test()

// function test(){
//   var a, b;
//   if(typeof(arguments[0]) !== 'undefined'){
//     a = 1;
//   }else{
//     a = arguments[0];
//   }
//   console.log(a + b);
// }

// n的阶层
// function fact(n){
//   if(n == 1){
//     return 1;
//   }
//   return n * fact(n -1);
// }


// 预编译
// 1.检查通篇的语法错误
// 1.5.预编译的过程
// 2.解释一行，执行一行

// 函数声明整体提升，变量只有声明提升，赋值是不提升的


// console.log(a);
// function a(a){
//   var a = 10;
//   var a = function(){

//   }
// }

// 暗示全局变量
// var a = 1;
// b = 2;
// console.log(a); //a = window.a
//                 //b = window.b
// window = {
//   a: 1,
//   b: 2
// }

// function test(){
//   var a = b = 1;  //b不是在function内部声明 挂到window
// }
// test()
// console.log(b);

// function test(a) {
//   var a = 1;
//   function a(){}

// }


// AO activation object 
// 活跃对象，函数上下文
  // 1.寻找形参和变量声明
  // 2.市场值赋值给形参
  // 3.找函数声明，赋值
  // 4.执行
  // AO =  {
  //   a : undefined -> 2 -> function(){} ->1
  //   b : undefined
  //   d : function(){}
  // }


  // function test(a, b){
  //   console.log(a);
  //   c = 0;
  //   var c;
  //   a = 5;
  //   b = 6;
  //   console.log(b);
  //   function b(){}
  //   function d(){}
  //   console.log(b);
  // }


  // var a = 1;
  // function a(){
  //   console.log(2);
  // }
  // console.log(a);
  // GO global object 全局上下文
  // GO = {
  //   a : undefined -> function a(){} -> 1
  // }

  // GO === window 


  // function test(){
  //   return a;
  //   a = 1;
  //   function a(){}
  //   var a = 2
  // }

  // AO: {
  //   a: undefined -> function a(){}
  // }
  // console.log(test());  // a() {...}

  // 找形参和变量声明
  // 实参附给形参
  // 寻找函数声明
  // 执行函数

  // console.log(test);
  // function test(){
  //   a = 1;
  //   function a(){}
  //   var a = 2;
  //   return a;
  // }
  // AO:{
  //   // a : undefined -> function a(){} -> 1 -> 2
  // }

  // 对象
  function test(a, b){

  }

  //函数也是一种对象属性 引用类型 引用值
  //test.name test.length test.prototype
  //对象 -> 有些属性是无法访问的
            // JS引擎内部固有的隐士属性
            //[[scope]] 作用域
            // 1.函数创建时，生成的一个js内部的隐式属性
            // 2.函数存储作用域链的容器，作用域链
                  // AO，GO
                  // AO 函数的执行其上下文
                  // GO 全局的执行期上下文
                  // 函数执行完成后 ao是要被销毁的
                  // ao是一个即时的存储容器

    // function a(){
    //   function b(){
    //     var b = 2;
    //   }
    //   var a = 1;
    //   b();
    // }
    // var c = 3;
    // a();
    
    // GO:{
    //   a : undefined -> function a(){}
    //   c : undefined;
    // }

    // 作用域链： scope chain
    //             0    函数a的ao
    //             1    go全局函数的执行期上下文

    //             首先会在ao查找，ao没有，则向go查找

    //             b函数被执行(前一刻)：生成函数b的[[scope]]，存储函数b的作用域链，顶端第0位存储b函数的ao，
    //             a函数的ao和全局的go依次向下排列
                    // 只要函数定义，生成作用域，作用域链，go放进去，当执行那一刻，生成自己的ao
  
  // 当内部函数被返回到外部被保存时，一定会产生闭包，闭包会产生原来的作用域链不释放，过度的闭包可能会导致内存泄露

// function test(){
//   var n = 100;
//   function add(){
//     n++;
//     console.log(n);
//   }

//   function reduce(){
//     n--;
//     console.log(n);
//   }

//   return [add,reduce]
// }

// var arr = test()
// arr[1]()
// arr[0]()
// arr[0]()

// var arr1 = test()
// arr1[0]();

// function sunSched(){
//   var sunSched = '';

//   var operation = {
//     setSched : function(thing){
//       sunSched = thing;
//     },
//     showSched : function(){
//       console.log('my schedule on sunday is'+sunSched);
//     }
//   }
//   return operation
// }

// var sunSche = sunSched()
// sunSche.setSched('working')
// sunSche.showSched()




// function Test(){
//   var a = 5;
//   console.log(a);
// }

// Test()

// function test(){
//   return a;
//   a = 1;
//   function a(){}
//   var a = 2;
// }
// console.log(test());  // function a(){}

// a = 1;
// function test(e){
//   function e(){}
//   arguments[0] = 2;
//   console.log(e);
//   if(a){
//     var b = 3;
//   }
//   var c;
//   a = 4;
//   var a;
//   console.log(b);
//   f = 5;
//   console.log(c);
//   console.log(a);
// }
// var a;
// test(1);
// console.log(a);
// console.log(f);

// GO:{
//   a : undefined -> 1
//   test: function test(){},
//   f: 5
// }

// AO:{
//   e:undefined -> 1 -> function e(){} -> 2
//   b:undefined,
//   c:undefined,
//   a:undefined -> 4
// }


// function test(){
//   a = 5
// }
// test()  // 如果test() 不执行，那么a = 5 不会变量提升至全局
// console.log(a);


console.log(test);
// function test(){
//   console.log(2);
// }

console.log(test);
var test = 1

console.log(test);

//疑问 ？ 函数声明 和 var 同名  那 声明的变量初始值 undefined在哪？